﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
    using System;
    using System.Collections.Generic;
    using System.Drawing;
    using Emgu.CV;
    using Emgu.CV.CvEnum;
    using Emgu.CV.Structure;
    using Emgu.CV.Util;
namespace WinFormsApp1
{


    public class WhiteBorderDetector4
    {
        /// <summary>
        /// 检测白色边框图形
        /// </summary>
        /// <param name="inputPath">输入图像路径</param>
        /// <param name="minBorderWidth">最小边框宽度（像素）</param>
        /// <returns>检测到的边框位置列表</returns>
        public static List<Rectangle> DetectWhiteBorders(string inputPath, int minBorderWidth = 10)
        {
            List<Rectangle> results = new List<Rectangle>();

            using (Mat src = CvInvoke.Imread(inputPath, ImreadModes.Color))
            using (Mat hsv = new Mat())
            {
                if (src.IsEmpty) throw new ArgumentException("无法加载图像");

            

                // 1. 动态颜色阈值处理
                CvInvoke.CvtColor(src, hsv, ColorConversion.Bgr2Hsv);
                Mat[] channels = hsv.Split();

                // 基于图像亮度自动调整阈值
                double meanV = CvInvoke.Mean(channels[2]).V0;
                int vThreshold = 200;// (int)(meanV > 150 ? 230 : 200);

                // 2. 创建颜色掩模
                Mat whiteMask = new Mat();
                CvInvoke.InRange(hsv,
                    new ScalarArray(new MCvScalar(0, 0, vThreshold)),
                    new ScalarArray(new MCvScalar(180, 30, 255)),
                    whiteMask);

                // 3. 形态学优化
                Mat kernel = CvInvoke.GetStructuringElement(ElementShape.Rectangle,
                    new Size(minBorderWidth, minBorderWidth), new Point(-1, -1));

                CvInvoke.MorphologyEx(whiteMask, whiteMask, MorphOp.Close, kernel,
                    new Point(-1, -1), 2, BorderType.Default, default);

       
                // 4. 轮廓检测与验证
                VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint();
                CvInvoke.FindContours(whiteMask, contours, null, RetrType.List,
                    ChainApproxMethod.ChainApproxSimple);

                for (int i = 0; i < contours.Size; i++)
                {
                    VectorOfPoint contour = contours[i];

                    // 4.1 几何特征验证
                    if (IsValidBorder(contour, src.Size, minBorderWidth))
                    {
                        Rectangle rect = CvInvoke.BoundingRectangle(contour);
                        results.Add(rect);
                    }
                }
            }
            return results;
        }
        public static List<Rectangle> DetectBordersAdvanced(string path, int minBorderWidth = 10)
        {
            List<Rectangle> results = new List<Rectangle>();

            using (Mat src = CvInvoke.Imread(path, ImreadModes.Color))
            using (Mat lab = new Mat())
            {
                if (src.IsEmpty) throw new ArgumentException("无法加载图像");

                // 1. 转换到LAB颜色空间
                CvInvoke.CvtColor(src, lab, ColorConversion.Bgr2Lab);

                // 2. 分离通道并增强对比度
                Mat[] channels = lab.Split();
                CvInvoke.Normalize(channels[0], channels[0], 0, 255, NormType.MinMax);

                // 3. 动态阈值处理
                Mat lightMask = new Mat();
                double meanL = CvInvoke.Mean(channels[0]).V0;
                int lowerThreshold = (int)(meanL > 150 ? 220 : 180);
                CvInvoke.Threshold(channels[0], lightMask, lowerThreshold, 255, ThresholdType.Binary);

                // 4. 结构特征增强
                Mat structureMap = new Mat();
                CvInvoke.MorphologyEx(
                            lightMask,                    // 输入图像
                            structureMap,                 // 输出图像
                            MorphOp.Gradient,             // 形态学操作类型
                            CvInvoke.GetStructuringElement( // 结构元素
                                ElementShape.Rectangle,
                                new Size(minBorderWidth, 1),
                                new Point(-1, -1)
                            ),
                            new Point(-1, -1),            // 锚点（默认中心）
                            2,                            // 迭代次数
                            BorderType.Default,            // 边界类型
                            new MCvScalar(255)            // 边界值（默认为0）
                        );

                // 5. 融合检测
                Mat finalMask = new Mat();
                CvInvoke.BitwiseAnd(lightMask, structureMap, finalMask);

                // 6. 轮廓分析与验证
                VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint();
                CvInvoke.FindContours(finalMask, contours, null, RetrType.External,
                    ChainApproxMethod.ChainApproxSimple);

                for (int i = 0; i < contours.Size; i++)
                {
                    if (ValidateBorder(src, contours[i], minBorderWidth))
                    {
                        results.Add(CvInvoke.BoundingRectangle(contours[i]));
                    }
                }
            }
            return results;
        }

        /// <summary>
        /// 边框综合验证
        /// </summary>
        private static bool ValidateBorder(Mat src, VectorOfPoint contour, int minWidth)
        {
            Rectangle rect = CvInvoke.BoundingRectangle(contour);

            // 1. 尺寸验证
            if (rect.Width < minWidth || rect.Height < minWidth) return false;

            // 2. 内外对比验证
            using (Mat roi = new Mat(src, rect))
            using (Mat innerRoi = new Mat(roi,
                new Rectangle(minWidth, minWidth, roi.Width - 2 * minWidth, roi.Height - 2 * minWidth)))
            {
                // 计算内外区域亮度差异
                var outerMean = CvInvoke.Mean(roi);
                var innerMean = CvInvoke.Mean(innerRoi);

                // 要求内部比外部暗至少20%
               // if (innerMean.V0 > outerMean.V0 * 0.8) return false;
            }

            // 3. 边缘连续性验证
            //using (Mat edgeMap = new Mat())
            //{
            //    CvInvoke.Canny(src, edgeMap, 50, 150);
            //    double edgeCoverage = CvInvoke.CountNonZero(new Mat(edgeMap, rect))
            //                       / (double)(rect.Width * rect.Height);
            //    return edgeCoverage > 0.2;
            //}
            return true;
        }
        /// <summary>
        /// 验证轮廓是否为有效边框
        /// </summary>
        private static bool IsValidBorder(VectorOfPoint contour, Size imageSize, int minWidth,int maxWidth=60)
        {
           
            // 1. 面积过滤
            double area = CvInvoke.ContourArea(contour);
            if (area < imageSize.Width * imageSize.Height * 0.01) return false;

            // 2. 多边形近似
            VectorOfPoint approx = new VectorOfPoint();
            CvInvoke.ApproxPolyDP(contour, approx, 0.05 * CvInvoke.ArcLength(contour, true), true);

            // 3. 几何形状验证
            if (approx.Size < 4) return false; // 仅检测四边形边框

            // 4. 边框连续性检查
            Rectangle rect = CvInvoke.BoundingRectangle(contour);
            if (rect.Width < minWidth || rect.Height < minWidth||rect.Width > maxWidth) return false;

            return true;
            // 5. 边缘强度验证
            //using (Mat edgeMap = new Mat())
            //{
            //    CvInvoke.Canny(new Mat(whiteMask, rect), edgeMap, 100, 200);
            //    double edgeDensity = CvInvoke.CountNonZero(edgeMap) / (double)edgeMap.Total;
            //    return edgeDensity > 0.3;
            //}
        }

        /// <summary>
        /// 可视化检测结果
        /// </summary>
        public static void VisualizeResult(string inputPath, string outputPath, List<Rectangle> borders)
        {
            using (Mat src = CvInvoke.Imread(inputPath))
            {
                foreach (var rect in borders)
                {
                    CvInvoke.Rectangle(src, rect, new MCvScalar(0, 255, 0), 3);
                }
                CvInvoke.Imwrite(outputPath, src);
            }
        }

        // 使用示例
        public static List<Rectangle> Main4(string b)
        {
            try
            {
                string input = b;
                string output = "output_"+b;

                //var borders = DetectBordersAdvanced(input,10);
                var borders = DetectWhiteBorders(input, 2);
                VisualizeResult(input, output, borders);


                Console.WriteLine($"检测到 {borders.Count} 个白色边框");
                Console.WriteLine("结果已保存至: " + output);
                return borders;
            }
            catch (Exception ex)
            {
                Console.WriteLine($"错误: {ex.Message}");
            }
            return null;
        }
    }
}
